//
//  SandboxFileHandle.swift
//  FileHandle
//
//  Created by Kun Huang on 2020/3/12.
//  Copyright © 2020 Kun Huang. All rights reserved.
//

import UIKit

public class HKSandboxFileHandle {
    
    public enum SandboxDirectory {
        /// 应用程序主目录的路径
        case home
        case documents
        case library
        /// 废弃的缓存文件 (Library/Caches)
        case cache
        /// 临时目录
        case tmp
    }
    
    
    /// 获取沙盒路径
    /// - Parameter directory: 沙盒文件
    public class func sandboxPath(directory:SandboxDirectory) -> String {
        switch directory {
        case .home:
            return NSHomeDirectory()
        case .documents:
            return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.path ?? ""
        case .library:
            return FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first?.path ?? ""
        case .cache:
            return FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first?.path ?? ""
        case .tmp:
            return NSTemporaryDirectory()
        }
    }
    
    /// 创建文件夹
    /// - Parameter path: 路径
    public class func creatDirectory(path:String) throws {
        
        if FileManager.default.fileExists(atPath: path) {return}
        
        do {
            try FileManager.default.createDirectory(atPath: path, withIntermediateDirectories: false, attributes: nil)
        } catch let error {
            throw error
        }
    }

    /// 获取文件夹下面的所有文件
    /// - Parameter path: 路径
    public class func filesInDirectory(path:String) -> [HKSandboxFileModel] {
        var files = [HKSandboxFileModel]()
        guard let array =  try? FileManager.default.contentsOfDirectory(atPath: path) else {
            return []
        }
        
        let timeZone = NSTimeZone.system
        let interval: TimeInterval = TimeInterval(timeZone.secondsFromGMT())
        for fileName in array {
    
            let fullPath = "\(path)/\(fileName)"
            
            if let info = try? FileManager.default.attributesOfItem(atPath: fullPath) {
                let isDir = (info[.type] as? FileAttributeType) == .typeDirectory
                let creatDate = (info[.creationDate] as? NSDate)?.addingTimeInterval(interval)
                let size = (info[.size] as? UInt64) ?? 0
                let fileExtension = URL(fileURLWithPath: fullPath).pathExtension
                let model = HKSandboxFileModel(fullPath: fullPath,
                                               creatDate: creatDate,
                                               isDir: isDir,
                                               size: size,
                                               fileExtension: fileExtension)
                files.append(model)
            }
        
        }
        return files
    }
    
    /// 文件分块
    /// - Parameters:
    ///   - path: 文件路径
    ///   - offset: 起始偏移量
    ///   - unitsize: 每块大小
    ///   - result: 分块回调
    public class func fileChunks(path:String, offset:Int, unitSize: Int, result:((_ datas:[Data]) -> Void)?) {
        guard let readSoftware = FileHandle(forReadingAtPath: path) else {return}
        let fileSize = Int(readSoftware.seekToEndOfFile())
        if fileSize > 0 {
            // 分块
            var chunksData = [Data]()
            var chunkOffset = offset
            // 分成多少块
            let chunks = (fileSize%unitSize == 0) ? (fileSize/unitSize) : (fileSize/unitSize + 1)
            if chunkOffset >= chunks {
                 result?([])
                return
            }
            for index in chunkOffset..<chunks {
                chunkOffset = index*unitSize
                readSoftware.seek(toFileOffset: UInt64(chunkOffset))
                if index == chunks - 1 {
                    let data = readSoftware.readDataToEndOfFile()
                    chunksData.append(data)
                } else {
                    let data = readSoftware.readData(ofLength: unitSize)
                    chunksData.append(data)
                }
            }
            readSoftware.closeFile()
        
            result?(chunksData)
        }
    }

}

public extension HKSandboxFileHandle {
    
    /// 单个文件大小
    /// - Parameter path: 文件路径
    class func fileSize(path:String) -> UInt64 {
        let manager = FileManager.default
        if manager.fileExists(atPath: path) {
          do {
              let attr = try manager.attributesOfItem(atPath: path)
              let size = attr[FileAttributeKey.size] as? UInt64 ?? 0
              return size
          } catch {
              return 0
          }
        }
        return 0
    }
    
    /// 文件夹下所有文件大小，文件夹下面没有文件夹了
    /// - Parameter path: 文件夹路径
    class func folderFileSize(path: String) -> UInt64 {
      if FileManager.default.fileExists(atPath: path) {
        return filesInDirectory(path: path).reduce(0, {return $0 + $1.size})
      }
      return 0
    }
}
